#include "kernel.h"

static void
uniprocessor_init(void)
{
	 sysconf.use_pic = 1;
	 sysconf.has_lapic = 0;
	 sysconf.use_lapic = 0;
	 sysconf.cpu_boot = 0;
	 sysconf.cpu_count = 1;
	 sysconf.ioapic_count = 0;
	 
	 cpu_ids[0] = 0;
	 cpus[0].valid = 1;
}

struct sysconf_t sysconf __attribute__ ((aligned (PAGE_SIZE)));
cpu_id_t cpu_ids[SMP_MAX_COUNT];
volatile struct cpu_t cpus[SMP_MAX_COUNT];

int
sys_init(void)
{
	 int err = 0;

	 sysconf.use_pic = 0;
	 sysconf.has_lapic = 0;
	 sysconf.use_lapic = 0;
	 sysconf.lapic_phys = 0;
	 sysconf.cpu_count = 0;
	 sysconf.ioapic_count = 0;

	 kprintf("sysconf: pic - %d, lapic - %d\n", sysconf.use_pic, sysconf.use_lapic);
	 
	 if (acpi_init() < 0)
	 {
		  if ((err = ppage_alloc(&sysconf.lapic_phys, PPAGE_CORE)) < 0)
			   return err;
			   
		  uint32_t pte = sysconf.lapic_phys | PTE_W;
		  if ((err = fix_addr((void *)lapic, &pte, 1)) < 0)
		  {
			   return err;
		  }
		  else memset((void *)lapic, 0, PAGE_SIZE);
		  /* Map it to ULAPIC */
		  vpt[PAGE_NUM(ULAPIC)] = sysconf.lapic_phys | PTE_U | PTE_P;
			   
		  kprintf("Run as in Uniprocessor\n");
		  uniprocessor_init();
	 }
	 else
	 {
		  uint32_t b;
		  cpuid(1, NULL, &b, NULL, NULL);
		  sysconf.cpu_boot = (b >> 24) & 0xff;
		  kprintf("LAPIC physical addr: %p, cpu boot = %d\n", sysconf.lapic_phys, sysconf.cpu_boot);
		  
		  uint32_t pte = sysconf.lapic_phys | PTE_W;
		  int err = 0;
		  if ((err = fix_addr((void *)lapic, &pte, 1)) < 0)
		  {
			   return err;
		  }
		  /* Map it to ULAPIC */
		  vpt[PAGE_NUM(ULAPIC)] = sysconf.lapic_phys | PTE_U | PTE_P;
		  kprintf("%d CPUs, %d I/O APICs found.\n", sysconf.cpu_count, sysconf.ioapic_count);
		  sysconf.has_lapic = 1;
	 }

	 /* Map sysconf */
	 vpt[PAGE_NUM(USYSCONF)] = PADDR(&sysconf) | PTE_U | PTE_P;
	 kprintf("sysconf: pic - %d, lapic - %d\n", sysconf.use_pic, sysconf.use_lapic);
	 
	 return 0;
}

